/**
 * @file RegProvider.h
 *
 *  @date 26 jan 2012
 *  @author ytc0039
 */

#ifndef REGPROVIDER_H_
#define REGPROVIDER_H_

#include <string>
#include <Helpers/RegMapper.h>

using namespace std;
/**
 * \class RegMapper RegMapper.h <Helpers/RegMapper.h>
 *
 * \ingroup HelperClasses
 *
 * \brief provides a template class for registering certain objects.
 *
 * For example there exists a certain amount of different expression.
 * To add a new just create a new class that inherits from IExp and
 * create the methods. An expression either connects to Terminal or
 * Non-Terminal . That means that there exists a Enumeration called
 * Terminals.
 *
 * The RegProvider can register for example a new expression
 * providing the RegClass in this case its a IExp, a RegType
 * Which is a Terminals, and when calling the constructor
 * you provide the method to get the key string from Terminals based on the
 * ordinal
 *
 * \todo IExp should have a static method to get the "IExp"
 */

template< class RegClass >
class RegProvider {
public:
	//typedef RegClass Reg_class; ///Redefinition of RegClass
	//typedef string (RegType::*keyFn)(); ///Function to get the keyStr

	typedef RegMapper<RegClass> InstancesVector;
	/**
	 * \brief Constructor, provide typeClass  and function to retrieve key
	 *
	 * TypeClasses are grouping classes provided, an example would be
	 * Enumeration classes.
	 *
	 * @see Enumeration
	 * @see RegMapper
	 * @see IExp
	 *
	 * @param typeClass What type class to use for example IExp
	 * @param keyFunction (See Enumeration) What key function to use to retrieve key string
	 */

	RegProvider()
	{

	}

	/**
	 * \brief Destructor
	 *
	 */
	virtual ~RegProvider(){

	}

	/**
	 * \brief Register a class with the
	 *
	 *
	 * Together with the Enumeration class this is a convenient
	 * way to use register. By providing ordinance number for the new class
	 * it is possible to get the key string.
	 *
	 * Example:
	 * RegType \rightarrow Enumeration
	 * RegClass \rightarrow IExp
	 * Enumeration Expression \rightArrow ordinance 2 , example add
	 *
	 *
	 * @param newClass
	 * @param ord
	 * @return
	 */
	bool RegisterClass(string key, RegClass newClass)
	{
		bool ret = true;


		m_regMap.add(key,newClass);
		return ret;
	}

	const vector< RegClass >& findAll(const string& keyStr)
	{
		return m_regMap.find(keyStr);
	}
private:
	static InstancesVector  m_regMap;
};

template< class RegClass >
typename RegProvider< RegClass >::InstancesVector RegProvider< RegClass >::m_regMap;



#endif /* REGPROVIDER_H_ */
